package com.rw.coco.expression;

import com.rw.coco.expression.parser.DiceExpressionParser;
import com.rw.coco.expression.parser.element.DiceNumberElement;
import com.rw.tool.util.expression.element.Calculation;
import com.rw.tool.util.expression.element.ExpressionElement;
import com.rw.tool.util.expression.expression.InfixExpression;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 特化骰子表达式
 * 在Water-Tool中有相同作用的中缀表达式
 * 但是这里因为有骰子的存在，所以需要特化
 */
public class DiceExpression extends InfixExpression {
    public DiceExpression(List<ExpressionElement> elements) {
        super(elements);
    }

    /**
     * 获得带有骰子表达式的字符串
     */
    public String toDiceString() {
        List<ExpressionElement> elements = getElements();
        StringBuilder sb = new StringBuilder();

        for (ExpressionElement element : elements) {
            if (element instanceof Calculation) {
                sb.append(" ").append(element).append(" ");
            } else if (element instanceof DiceNumberElement) {
                DiceNumberElement diceNumberElement = (DiceNumberElement) element;
                sb.append(diceNumberElement.toDiceString());
            } else {
                sb.append(element);
            }
        }

        return sb.toString();
    }

    /**
     * 获得每个骰子详细情况的字符串
     */
    public String toDetailString(boolean simple) {
        List<ExpressionElement> elements = getElements();

        // 如果元素只有一个，而且为骰子元素，则不加括号
        if (elements.size() == 1 && elements.get(0) instanceof DiceNumberElement) {
            return ((DiceNumberElement) elements.get(0)).toAfterDiceString(simple);
        }

        StringBuilder sb = new StringBuilder();

        for (ExpressionElement element : elements) {
            if (element instanceof Calculation) {
                sb.append(" ").append(element).append(" ");
            } else if (element instanceof DiceNumberElement) {
                DiceNumberElement diceNumberElement = (DiceNumberElement) element;
                sb.append(diceNumberElement.afterDiceWithCast(simple));
            } else {
                sb.append(element);
            }
        }

        return sb.toString();
    }

    /**
     * 把 toDiceString() 和 toDetailString() 和 calculation() 进行拼接
     * 输出最终的整洁字符串
     */
    public String toCompleteString(boolean simple) {
        List<String> expressionList = new ArrayList<>();
        expressionList.add(toDiceString());
        expressionList.add(toDetailString(simple));
        expressionList.add(calculation().toString());

        // 由于表达式可能重复，所以需要去重
        return expressionList.stream().distinct().collect(Collectors.joining(" = "));
    }

    public static DiceExpression parse(String expression) {
        return parse(expression, 100);
    }

    /**
     * 解析字符串，使其变为合法的表达式列表
     * 如果字符串不符合中缀表达式结构，则会抛出异常
     * scale代表精确到小数点后几位
     */
    public static DiceExpression parse(String expression, int defaultDice) {
        DiceExpressionParser diceExpressionParser = new DiceExpressionParser(defaultDice);
        return diceExpressionParser.parseDiceExpression(expression);
    }
}
